
# global imports
import os.path
import Globals
from OFS import Folder
from Globals import HTMLFile
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
import AccessControl
import permissions

# package imports

import bug, interfaces, utils

# some gobals
_wwwDir = os.path.join(os.path.dirname(__file__), 'www')

# constructors
manage_addBugRepositoryForm = HTMLFile("www/addBugRepository", globals())

def manage_addBugRepository(container, id, title="", REQUEST=None):
    """Add a new bug repo to the current folder, with provided id and title
    if a request is passed, we redirect to the container management interface,
    otherwise we return the created object."""

    # create the object
    ob = BugRepository(id, title)
    # add it to the container
    container._setObject(id, ob)
    # get it back, wrapped in the container
    ob = container._getOb(id)
    if REQUEST is not None:
        # where do we go now?
        if REQUEST.get("addAndEdit"):
            # user pressed the [Add and Edit] button
            target = ob
        else:
            # user just pressed the [Add] button
            target = container
        url = target.absolute_url() + '/manage_main'
        return REQUEST.RESPONSE.redirect(url)
    # well, no request, return the object
    return ob

class BugRepository(Folder.Folder):
    """A Bug Repository"""
    # security object to make calls ans objects secure
    security = AccessControl.ClassSecurityInfo()
    security.setPermissionDefault(permissions.ADD_BUG_REPOSITORY, ('Manager'))
    security.setPermissionDefault(permissions.ADD_BUG, ('Manager', 'Customer'))
    security.declareObjectProtected(AccessControl.Permissions.access_contents_information)

    __implements__ = interfaces.IBugRepository


    _properties = ({'id':'title', 'type':'string', 'mode':'w'},)

    title = ''

    # Zope standard attributes
    meta_type = "DDBug Repository"
    
    # other class attributes
    bugIdMask = "%04d" # the format for the bug ids

    def __init__(self, id, title=""):
        self.id = id
        self.title = title
        self.MasterBug = bug.Bug(id="MasterBug")

    security.declareProtected(AccessControl.Permissions.view, 'bugIds')
    def bugIds(self):
        return self.objectIds(bug.Bug.meta_type)

    security.declareProtected(AccessControl.Permissions.view, 'bugValues')
    def bugValues(self, open=None):
        if open is None:
            return self.objectValues(bug.Bug.meta_type)
        else:
            return [b for b in self.objectValues(bug.Bug.meta_type) if b.open()==open]

##     def bugItems(self):
##         return self.objectItems(bug.Bug.meta_type)

    security.declarePrivate("xlate")
    # self will be passed in automatically as the context
    xlate = utils.xlate

    security.declareProtected(AccessControl.Permissions.view, 'getNextId')
    def getNextId(self):
        ids = self.bugIds()
        if not ids:
            # well, well, our very first bug id...
            nextIdNumber = 1
        else:
            # take the last guy out and get it's number value
            ids.sort()
            lastId = ids[-1]
            nextIdNumber = int(lastId) + 1
        # finally, we build the id
        nextId = self.bugIdMask % nextIdNumber
        return nextId

    security.declareProtected(permissions.ADD_BUG, 'newBug')
    def newBug(self):
        """Creates a new bug in the repository, but doesn't change
        anything in the new bug
        """
        bugId = self.getNextId()
        # this was the old way.
        #theBug = bug.Bug(id=bugId)
        #self._setObject(bugId, theBug)
        #theBug = self[bugId] # get the wrapped version
        
        # in the new way we just clone the MasterBug
        theBug = self.manage_clone(self.MasterBug, bugId)
        return theBug

    security.declareProtected(AccessControl.Permissions.view, 'getRepository')
    def getRepository(self):
        return self

    # Main view    
    index_html  = PageTemplateFile('index_html.pt', _wwwDir)
    security.declareProtected(permissions.ADD_BUG, 'index_html')
    
    
    index2_html = PageTemplateFile('index2_html.pt', _wwwDir)
    security.declareProtected(permissions.ADD_BUG, 'index2_html')
    
    index3_html = PageTemplateFile('index3_html.pt', _wwwDir)
    security.declareProtected(permissions.ADD_BUG, 'index3_html')

    report      = PageTemplateFile('report.pt', _wwwDir)
    security.declareProtected(permissions.ADD_BUG, 'report')

    # Form to add bugs
    security.declareProtected(permissions.ADD_BUG, 'manage_addBugForm')
    manage_addBugForm = PageTemplateFile('addBugForm.pt', _wwwDir)
    
    # CSS for the form
    stylesheet = HTMLFile("www/stylesheet", globals())

    security.declareProtected(AccessControl.Permissions.view, 'stylesheet')

    security.declareProtected(permissions.ADD_BUG, 'manage_addBug')
    def manage_addBug(self, REQUEST=None, **kw):
        """create a bug"""
        theBug = self.newBug()
        theBug.manage_editBug(REQUEST, **kw)
        # go back to the main listing in the bug repo
        if REQUEST is not None:
            REQUEST.RESPONSE.redirect(self.absolute_url())
        else:
            return theBug

    security.declareProtected(AccessControl.Permissions.view,
                              'getAuthenticatedUser')
    def getAuthenticatedUser(self):
        return AccessControl.getSecurityManager().getUser()

    security.declareProtected(AccessControl.Permissions.view,
                              'getFilteredRoles')
    def getFilteredRoles(self):
        '''filtered roles to show in templates'''
        rolesToFilterOut = ['Authenticated', 'Owner']
        return [role for role in self.getAuthenticatedUser().getRolesInContext(self) if role not in rolesToFilterOut]

    security.declareProtected(AccessControl.Permissions.view,
                              'getFilteredRolesStr')
    def getFilteredRolesStr(self):
        return ", ".join(self.getFilteredRoles())

    security.declareProtected(AccessControl.Permissions.view, 'listByProperty')
    def listByProperty(self, property, value):
        bugs = []
        for bug in self.bugValues():
            if getattr(bug, property) == value:
                bugs.append(bug)
        return bugs

##     _propertySortOrder = ('priority', 'severity', 'status')
##     def _sortedBugs(property=None):
##         # get an changeable copy of the sort order
##         propertySortOrder = list(self._propertySortOrder)
##         if property:
##             # sort by a certain property first
##             propertySortOrder.remove(property)
##             propertySortOrder.insert(0, property)

    security.declareProtected(AccessControl.Permissions.view,
                              'dumpBugsByProperty')
    def dumpBugsByProperty(self, property, open=1):
        "returns a list of dicts [ { 'property': <value>, 'bugs':buglist}... ]"
        Property = property.capitalize()
        valueLister = getattr(self.MasterBug, "optionsFor" + Property)
        propertyValues = valueLister()
        dump = []        
        for value in propertyValues:
            bugs = self.listByProperty(property, value)
            ls = []
            for b in bugs:
                if b.open() == open:
                    if property == 'priority':
                        ls.append((b.optionsForSeverity().index(b.severity),b))
                    else:
                        ls.append((b.priority, b))
            ls.sort()
            bugs = [b for i, b in ls]
            if bugs:
                getLabel = getattr(self.MasterBug,
                                  "get"+ Property + "Label")
                value = getLabel(value)
                # i.e.: value = self.MasterBug.getSeverityLabel(value)
                dump.append({property:value, 'bugs':bugs})
        return dump

    security.declareProtected(AccessControl.Permissions.view, 'dumpBugsByPriority')
    def dumpBugsByPriority(self, open=1):
        "returns a list of dicts {'priority','bugs'}"
        return self.dumpBugsByProperty('priority', open=open)
        

    security.declareProtected(AccessControl.Permissions.view, 'dumpBugsByStatus')
    def dumpBugsByStatus(self, open=1):
        "returns a list of dicts {'status','bugs'}"
        return self.dumpBugsByProperty('status', open=open)

    security.declareProtected(AccessControl.Permissions.view, 'dumpBugsBySeverities')
    def dumpBugsBySeverities(self, open=1):
        "returns a list of dicts {'status','bugs'}"
        return self.dumpBugsByProperty('severity', open=open)
        
    security.declareProtected(AccessControl.Permissions.view, 'getProductTitle')
    def getProductTitle(self):
        title = self.manage_addProduct['DDBug'].title
        try:
            # Try to get text between ()
            return title[title.index('(')+1:title.index(')')]
        except ValueError:
            return title

    def getTotalOfProperty(self,property, open):
        total = 0
        for b in self.bugValues():
            if b.open() == open:
                total += getattr(b,property)
        return total
    
    def getTotalOfEstimatedTimeToFix(self, open):
        """return  de total of estimated_time_to_fix property"""
        return self.getTotalOfProperty('estimated_time_to_fix', open)

    def getTotalOfactualTimeToFix(self, open):
        """return  de total of actual_time_to_fix property"""
        return self.getTotalOfProperty('actual_time_to_fix', open)

# Leo:
# the steps of the constructor wizard, conveniently packed into a
# single variable for the benefit of context.registerClass in
# __init__.initialize()
bugRepositoryConstructors = (manage_addBugRepositoryForm,
                             manage_addBugRepository)

Globals.InitializeClass(BugRepository)
